package com.mazaiting.rtda.heap;

import com.mazaiting.classfile.attr.MemberInfo;
import com.mazaiting.classfile.attr.info.ConstantValueAttribute;
import java.util.Objects;

/**
 * 字段
 * Field结构体比较简单，目前所有信息都是从ClassMember中继承过来的
 *
 * @author mazaiting
 * @since 2021/8/16
 */
public class MtField extends MtClassMember {
    /**
     * 编号
     */
    private int slotId;
    /**
     * 常量值索引
     */
    private int constValueIndex;

    /**
     * 创建字段数组
     *
     * @param mtClass     类
     * @param memberInfos 成员信息
     * @return 字段数组
     */
    public static MtField[] newFields(MtClass mtClass, MemberInfo[] memberInfos) {
        MtField[] fields = new MtField[memberInfos.length];
        for (int i = 0; i < fields.length; i++) {
            MtField mtField = new MtField();
            mtField.setMtClass(mtClass);
            mtField.copyMemberInfo(memberInfos[i]);
            mtField.copyAttributes(memberInfos[i]);
            fields[i] = mtField;
        }
        return fields;
    }

    /**
     * 复制属性
     *
     * @param info 成员信息
     */
    private void copyAttributes(MemberInfo info) {
        ConstantValueAttribute attr = info.valueAttribute();
        if (Objects.nonNull(attr)) {
            this.constValueIndex = attr.getConstantValueIndex();
        }
    }

    /**
     * 判断是否为父类
     *
     * @return true: 包含; false: 不包含
     */
    public boolean isVolatile() {
        return MtAccessFlags.isVolatile(accessFlags);
    }

    /**
     * 判断是否为transient
     *
     * @return true: 包含; false: 不包含
     */
    public boolean isTransient() {
        return MtAccessFlags.isVolatile(accessFlags);
    }

    /**
     * 判断是否为枚举
     *
     * @return true: 包含; false: 不包含
     */
    public boolean isEnum() {
        return MtAccessFlags.isEnum(accessFlags);
    }

    /**
     * 判断是否为 long 或者 double
     *
     * @return true: 是; false: 不是
     */
    public boolean isLongOrDouble() {
        return Objects.equals(descriptor, "J") || Objects.equals(descriptor, "D");
    }

    public void setSlotId(int slotId) {
        this.slotId = slotId;
    }

    public int getSlotId() {
        return slotId;
    }

    public int getConstValueIndex() {
        return constValueIndex;
    }

    @Override
    public String toString() {
        return "MtField{" +
                "name='" + name + '\'' +
                ", descriptor='" + descriptor + '\'' +
                '}';
    }
}


















